﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using DH.Web.Controllers;
using DH.Entity;
using DH.Service.ViewModels;
using DH.Service.Domain;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using Microsoft.AspNetCore.Authorization;
using DH.Web.Attributes;
using System.ComponentModel;
using DH.Core;
using Newtonsoft.Json;
using DH.Web.MVC.Extensions;
using System.Reflection;
using DH.Core.Helper;

namespace DH.Web.MVC.Controllers
{
    [Authorize]
    [Route("Features")]
    [Resource("Features(资源)")]
    [Description("Features(资源)")]
    [Guid("8e7c5db8-8e29-49ed-97cf-dbdaf3fd4c8e")]
    public class FeaturesController : SiteController<FeaturesEntity, FeaturesViewModel, string>
    {
        FeaturesService _featuresService;
        UiFeaturesButtonService _uiFeaturesButtonService;
        //protected IServiceCollection _service;
        
        static Logger Logger = LogManager.GetCurrentClassLogger();
        public FeaturesController(IServiceCollection serviceCollection,
                              FeaturesService featuresService) : base(serviceCollection, featuresService)
        {
            _featuresService = featuresService;
            //_service = serviceCollection;

            _uiFeaturesButtonService= _service.BuildServiceProvider().GetService<UiFeaturesButtonService>();
           
        }

        [HttpGet]
        [Route("Index")]
        [UIView("Features首页")]
        [Description("Features首页")]
        [Guid("35893fe3-be50-4a8c-9d4d-21defea7e374")]
        public IActionResult Index()
        {
            ViewBag.CurrentUser = CurrentUserEx;
            ViewBag.CurrentViewId = "35893fe3-be50-4a8c-9d4d-21defea7e374";
            return View();
        }

        [HttpGet]
        [Route("GetFeatures")]
        [Function("获取Features列表")]
        [Description("获取Features列表")]
        [Guid("5b768353-99ad-4a0c-9c7d-828854a33da2")]
        public IActionResult GetFeaturesList()
        {
            var categoryService= _service.BuildServiceProvider().GetService<CategoryService>(); 
            PagedData<FeaturesViewModel> models;
            var pagination = GetPagination();
            var queryKey = "";
            var queryKeys = Request.Query["queryKey"];
            if (queryKeys.Any())
            {
                queryKey = queryKeys[0];
            }

            var filterObj = new FeaturesQueryDto();
            var filter = Request.Query["filter"];
            if (filter.Any())
            {
                if (filter[0] != "")
                {
                    filterObj = JsonConvert.DeserializeObject<FeaturesQueryDto>(filter[0]);
                }

            }

            //排序字段和方式
            var sortNameStr = "";
            var sortOrderStr = "asc";
            var sortName = Request.Query["sortName"];
            var sortOrder = Request.Query["sortOrder"];
            if (sortName.Any())
            {
                sortNameStr = sortName[0];
            }
            if (sortOrder.Any())
            {
                sortOrderStr = sortOrder[0];
            }


            var res = _featuresService.GetList(queryKey, sortNameStr, sortOrderStr, filterObj, pagination);
            models = res.ToViewModelPageData<FeaturesEntity, FeaturesViewModel>();

            foreach (var m in models.DataList)
            {
               var categoryObj=categoryService.GetCategoryById(m.ResourceTypeId);
                if (categoryObj!=null)
                {
                    m.ResourceTypeId = categoryObj.Id;
                    m.ResourceTypeName = categoryObj.Name;
                    m.ResourceTypeCode = categoryObj.Code;
                }
            }


            var result = new { total = models.TotalCount, rows = models.DataList };
            return Json(result);
        }

        [HttpGet]
        [Route("InitFeatures")]
        [Function("初始化功能", isManage: true)]
        [Description("初始化功能")]
        [Guid("72380ff7-d0c7-4b77-abe6-43feacd1af5a")]
        public IActionResult InitFeatures()
        {
            //不是开发人员，无权执行
            if (!CurrentUser.IsDeveloper)
            {
                return InternalServerError(null, "非开发人员，无权执行此操作");
            }
            try
            {
                //生成功能
                var res = ImportFeatures();
                if (res)
                {
                    return SuccessMessage("系统功能初始化成功");
                }
                else
                {
                    return Error("系统功能初始化失败");
                }


            }
            catch (Exception ex)
            {
                Logger.Error("初始化系统功能发生异常：" + ex.Message);
                return InternalServerError(ex, "Error while initing Features");
            }
        }

        private bool ImportFeatures()
        {
            var assemblyStrings = new List<string> {
                            "DH.Web.MVC"
                        };
            var dlls = assemblyStrings.Select(Assembly.Load).ToList();

            var oldFeatures = _featuresService.GetAllFeatures();

            var categories = new List<FeaturesViewModel>();

            foreach (var dll in dlls)
            {
                var types = dll.GetTypes();
                var controllerType = typeof(Web.Controllers.ControllerBase);

                foreach (var t in types)
                {
                    var isController = controllerType.IsAssignableFrom(t);//继承ControllerBase 的控制器
                    if (!isController)
                    {
                        continue;
                    }
                    //获取资源名称
                    var controllerName = t.Name.Substring(0, t.Name.Length - "Controller".Length);
                    var resourceName = controllerName;//没有资源名称，默认取控制器名称
                    var resourceAttributes = t.GetCustomAttributes(typeof(ResourceAttribute), inherit: false);
                    if (resourceAttributes.Length > 0)
                    {
                        var description = ((ResourceAttribute)resourceAttributes[0]).Description;
                        if (!string.IsNullOrWhiteSpace(description))
                        {
                            resourceName = description;
                        }

                    }
                    else
                    {
                        continue;
                    }
                    var guidAttribute = t.GetCustomAttribute(typeof(GuidAttribute));
                    if (guidAttribute==null)
                    {
                        continue;
                    }
                    var resourceGuid = ((GuidAttribute)guidAttribute).Description;
                    if (string.IsNullOrWhiteSpace(resourceGuid))
                    {
                        continue;
                    }

                    var features = t.GetMethods();
                    foreach (var res in features)
                    {
                        var isAction = (typeof(IActionResult)).IsAssignableFrom(res.ReturnType);
                        var isAsyncResultAction = (typeof(Task<IActionResult>)).IsAssignableFrom(res.ReturnType);
                        if (!isAction&&!isAsyncResultAction)
                        {
                            continue;
                        }

                        var funcGuidAttribute= res.GetCustomAttribute(typeof(GuidAttribute));
                        if (funcGuidAttribute==null)
                        {
                            continue;
                        }
                        var funcGuid= ((GuidAttribute)funcGuidAttribute).Description;
                        if (string.IsNullOrEmpty(funcGuid))
                        {
                            continue;
                        }

                        var funcCodeAttribute= res.GetCustomAttribute(typeof(RouteAttribute));
                        if (funcCodeAttribute==null)
                        {
                            continue;
                        }
                        var funcCode= ((RouteAttribute)funcCodeAttribute).Template;
                        if (string.IsNullOrEmpty(funcCode))
                        {
                            funcCode = res.Name;
                        }

                        var isUIView = res.GetCustomAttribute(typeof(UIViewAttribute));
                        var isFunc = res.GetCustomAttribute(typeof(FunctionAttribute));

                        var isFuncBool = false;
                        var isUIViewBool = false;
                        var isManage = false;
                        var description = "";
                        if (isUIView == null && isFunc == null) {
                            continue;
                        }
                        if (isUIView!=null&&isFunc==null)
                        {
                            //功能视图
                            isManage = false;

                            isUIViewBool = true;

                            description = ((UIViewAttribute)isUIView).Description;
                        }
                        if (isUIView==null&&isFunc!=null)
                        {
                            //功能
                            var isManageAttribute = ((FunctionAttribute)isFunc).IsManage;
                            isManage = isManageAttribute;

                            isFuncBool = true;

                            description = ((FunctionAttribute)isFunc).Description;
                        }

                        if (string.IsNullOrEmpty(description))
                        {
                            var funcDesciptionAttribute = res.GetCustomAttribute(typeof(DescriptionAttribute));
                            if (funcDesciptionAttribute != null)
                            {
                                description = ((DescriptionAttribute)funcDesciptionAttribute).Description;
                            }

                        }

                        var existResources = oldFeatures.Where(c => c.Id == funcGuid);
                        if (!existResources.Any())
                        {
                            //生成实体
                            var featuresViewModel = new FeaturesViewModel();
                            featuresViewModel.Id = funcGuid;
                            featuresViewModel.ResourceTypeId = resourceGuid;
                            if (isUIViewBool)
                            {
                                featuresViewModel.Type = ConstHelper.FeaturesUIViewType;
                            }
                            else if (isFuncBool)
                            {
                                featuresViewModel.Type = ConstHelper.FeaturesFuncType;
                            }
                            featuresViewModel.IsManage = isManage;
                            featuresViewModel.Status = true;
                            featuresViewModel.Code = funcCode;
                            featuresViewModel.Description = description;
                            featuresViewModel.CreatedBy = CurrentUser.UserId;
                            featuresViewModel.UpdatedBy = CurrentUser.UserId;


                            categories.Add(featuresViewModel);
                        }

                    }


                    

                }
            }
            //批量保存
            _featuresService.InsertFeatures(categories);

            return true;

        }


        [HttpGet]
        [Route("GetFuncs")]
        [Function("获取资源功能")]
        [Description("获取资源功能")]
        [Guid("1dbd3d3a-42f1-45cd-b700-0fecbc5b7867")]
        public IActionResult GetFuncs()
        {
            var resourceTypeIdStr = "";
            var resourceTypeId= Request.Query["resourceId"];
            if (resourceTypeId.Any())
            {
                resourceTypeIdStr = resourceTypeId[0];
            }


            var res = _featuresService.GetFeatures(true, true,resourceTypeIdStr, ConstHelper.FeaturesFuncType);
            return new JsonResult(res);
        }

        [HttpPost]
        [Route("SaveUiViewButtonsFunc")]
        [Function("存储视图功能按钮功能",isManage:true)]
        [Description("存储视图功能按钮功能")]
        [Guid("d0573c12-7c68-4d10-9578-18a1d22265fe")]
        public IActionResult SaveUiViewButtonsFunc(List<UiViewFeaturesBtnFuncDto> viewDtos)
        {
            try
            {
                var request = Request;

                var viewModes = new List<UiFeaturesButtonViewModel>();
                foreach (var dto in viewDtos)
                {
                    var viewModel = new UiFeaturesButtonViewModel();
                    viewModel.Id = Guid.NewGuid().ToString();
                    viewModel.CreatedBy = CurrentUser.UserId;
                    viewModel.UpdatedBy = CurrentUser.UserId;
                    viewModel.UiViewId = dto.UiViewId;
                    viewModel.ButtonId = dto.ButtonId;
                    viewModel.FeatureId = dto.FeatureId;
                    viewModel.SortIndex = dto.SortIndex;
                    viewModel.Status = true;
                    viewModel.Description = "";
                    viewModes.Add(viewModel);
                }

                var res = _uiFeaturesButtonService.Add(viewModes);

                return SuccessMessage("执行成功");
            }
            catch (Exception ex)
            {
                Logger.Error("存储视图按钮功能时发生异常：" + ex.Message);
                return InternalServerError(ex, "Error while save view buttons : {0}", nameof(UiViewFeaturesBtnFuncDto));
            }
        }


        [HttpGet]
        [Route("GetUiViewButtonsFunc")]
        [Function("获取视图按钮功能")]
        [Description("获取视图按钮功能")]
        [Guid("2f880c10-60a0-438e-9bf7-a481d8a462fa")]
        public IActionResult GetUiViewButtonsFunc(string uiViewId)
        {
            var res = _uiFeaturesButtonService.GetList(uiViewId);

            return new JsonResult(res);
        }

        [HttpGet]
        [Route("GetFeaturesFuncs")]
        [Function("获取资源功能")]
        [Description("获取资源功能")]
        [Guid("787a4a0f-c896-4d0e-8a08-fdbea527828b")]
        public IActionResult GetFeaturesFuncs(string resourceId)
        {
            var res = _featuresService.GetResourceFeatures(resourceId);
            return new JsonResult(res);
        }

        

    }
}